/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-05
 * V4.0
 */
package com.jphenix.service.nodeloader.instancea;

import java.io.File;

import com.jphenix.driver.nodehandler.exception.NodeHandlerException;
import com.jphenix.driver.nodehandler.instancea.NodeHandler;
import com.jphenix.kernel.baseobject.instanceb.ABase;
import com.jphenix.kernel.objectloader.interfaceclass.IBean;
import com.jphenix.service.objectcase.instancea.ObjectCase;
import com.jphenix.servlet.filter.FilterExplorer;
import com.jphenix.share.tools.FileCopyTools;
import com.jphenix.share.util.SFilesUtil;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.objectcase.IObjectCase;
import com.jphenix.standard.servlet.IActionContext;
import com.jphenix.standard.servlet.IBytesFilter;
import com.jphenix.standard.viewhandler.INodeHandler;
import com.jphenix.standard.viewhandler.INodeLoader;

/**
 * 节点解析类加载容器
 * 
 * 2020-08-02 去掉了加载jar内部模板功能，改用独立的控制台过滤器来处理
 * 
 * com.jphenix.service.nodeloader.instancea.NodeLoader
 * @author 刘虻
 * 2007-1-1下午10:04:51
 */
@ClassInfo({"2020-08-02 20:41","节点解析类加载容器"})
public class NodeLoader extends ABase implements INodeLoader {

	protected FilterExplorer fe = null;         //主过滤器 
	protected boolean singleton = true;			//是否驻留到缓存中
	protected IObjectCase objectCase = null;	//容器
	protected String 
					dealEncoding = null			//程序节点编码格式
					,basePath = null			//页面根路径
					,xmlModelExtName = null;	//xml模板扩展名
	
	/**
	 * 构造函数
	 * 2007-1-1下午10:04:52
	 */
	public NodeLoader(IBean bean) {
		super();
		setBase(bean);
		fe = bean(FilterExplorer.class);
		basePath = fe.getWebBasePath();
	}
	
	/**
	 * 设置页面根路径
	 * 刘虻
	 * 2010-5-18 下午12:48:03
	 * @param basePath 页面根路径
	 */
	@Override
    public void setBasePath(String basePath) {
		this.basePath = basePath;
	}
	
	/**
	 * 获取页面根路径
	 * 刘虻
	 * 2010-5-18 下午12:48:15
	 * @return 页面根路径
	 */
	@Override
    public String getBasePath() {
		return basePath;
	}
	
	
	/**
	 * 获取新的节点解析类实例
	 * @author 刘虻
	 * 2007-4-5下午03:43:00
	 * @return 新的节点解析类实例
	 */
	@Override
    public INodeHandler getNewNode() {
		//构建一个新实例
		INodeHandler nodeHandler = new NodeHandler();
		nodeHandler.setDealEncode(getDealEncoding()); //设置程序编码
		return nodeHandler;
	}
	
	
	/**
	 * 加载指定文件
	 * 刘虻
	 * 2010-6-8 下午05:31:08
	 * @param subPath 视图文件网站相对路径
	 * @param ac      动作上下文
	 * @return 视图类实例
	 * @throws Exception 执行发生异常
	 */
	@Override
    public INodeHandler getNode(String subPath, IActionContext ac) throws Exception {
		if(subPath==null || subPath.length()<1) {
			throw new NodeHandlerException("The Node SubPath is Null");
		}
		INodeHandler newNode = null; //构建返回值
		byte[] nodeBytes = null;     //内容信息字节数组
		//目标文件
		File nodeFile = new File(SFilesUtil.getAllFilePath(subPath,basePath));
		if(nodeFile.exists()) {
			//存在本地文件
			if(singleton) {
				//先从缓存中获取
				newNode = (INodeHandler)getObjectCase().getObject(CASE_ID,subPath);
				if(newNode!=null && newNode.getTS()==nodeFile.lastModified()) {
					return (NodeHandler)newNode.clone();
				}
			}
			//构造新实例
			newNode = getNewNode();
			newNode.setDealEncode("UTF-8");
			newNode.setXmlStyle(subPath.endsWith(getXmlModelExtName()));
			
			
			nodeBytes = FileCopyTools.copyToByteArray(nodeFile);
			
			//执行解析
			for(IBytesFilter ele:fe.getByteFilterList()) {
				nodeBytes = ele.doBytesFilter(nodeBytes,ac.getRequest(),ac.getResponse());
			}
			//设置内容
			newNode.setBytes(nodeBytes);
			if(singleton) {
				//放入容器
				getObjectCase().setObject(CASE_ID,subPath,newNode);
			}
			return (NodeHandler)newNode.clone();
		}
		//不存在本地文件
		return null;
		
		/*
    	
    	禁止输出内部文件
    	
    	//获取内部资源
    	JarResourceVO resVO = fe.loadInsideResource(subPath);
    	if(resVO==null) {
    		return null;
    	}
		//构造新实例
		newNode = getNewNode();
		newNode.setDealEncode("UTF-8");
		newNode.setXmlStyle(subPath.endsWith(getXmlModelExtName()));
		
		nodeBytes = FileCopyTools.copyToByteArray(resVO.jarFile.getInputStream(resVO.entrie));
		//执行解析
		for(IBytesFilter ele:fe.getByteFilterList()) {
			nodeBytes = ele.doBytesFilter(nodeBytes,ac.getRequest(),ac.getResponse());
		}
		//设置内容
		newNode.setBytes(nodeBytes);
		if(singleton) {
			//放入容器
			getObjectCase().setObject(CASE_ID,subPath,newNode);
		}
		return (NodeHandler)newNode.clone();
		*/
	}
	

	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2007-1-1下午10:04:52
	 */
	public void setNode(
			String filePath
			, INodeHandler node) throws Exception {
		getObjectCase().setObject(CASE_ID,filePath,node);
	}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2007-1-2上午12:05:52
	 */
	public void clear() {}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2007-1-2上午12:10:31
	 */
	public boolean isSingleton() {
		return singleton;
	}


	/**
	 * 设置是否将模版驻留内存
	 * 刘虻
	 * 2010-5-18 下午12:39:36
	 * @param singleton 是否将模版驻留内存
	 */
	public void setSingleton(boolean singleton) {
		this.singleton = singleton;
	}
	
	
	/**
	 * 设置对象容器
	 * 刘虻
	 * 2010-5-18 下午12:41:13
	 * @param objectCase 对象容器
	 */
	public void setObjectCase(IObjectCase objectCase) {
		this.objectCase = objectCase;
	}

	/**
	 * 覆盖方法 
	 * @author  刘虻
	 * 2006-7-18 16:50:48
	 */
	public IObjectCase getObjectCase() {
		if(objectCase==null) {
			objectCase = new ObjectCase();
		}
		return objectCase;
	}


	/**
	 * 获取程序编码
	 * @author 刘虻
	 * 2007-4-6上午10:10:03
	 * @return 程序编码
	 */
	@Override
    public String getDealEncoding() {
		return dealEncoding;
	}
	


	/**
	 * 设置程序编码
	 * @author 刘虻
	 * 2007-4-6上午10:10:52
	 * @param dealEncoding 程序编码
	 */
	public void setDealEncoding(String dealEncoding) {
		this.dealEncoding = dealEncoding;
	}

	/**
	 * 获取XML视图模板扩展名
	 * 刘虻
	 * 2010-6-8 下午05:38:04
	 * @return XML视图模板扩展名
	 */
	public String getXmlModelExtName() {
		if(xmlModelExtName==null) {
			xmlModelExtName = "xml";
		}
		return xmlModelExtName;
	}
	
	/**
	 * 设置XML视图模板扩展名
	 * 刘虻
	 * 2010-6-8 下午05:38:26
	 * @param xmlModelExtName XML视图模板扩展名
	 */
	public void setXmlModelExtName(String xmlModelExtName) {
		this.xmlModelExtName = xmlModelExtName;
	}

}
